#include <func.h>
#include "command.h"

#define BUFFERSIZE 4096
//1、使用TCP协议通信，TCP可靠的，全双工，面向连接，字节流协议
//socket就是一个文件描述符fd来代表，unsigned int 类型
//
//2、TCP传输是一个字节流协议，没有消息边界，
//人为设定一个协议，一个结构体，有确定的大小，
//发送方，接收方遵守这个结构体大小，字节流就有了确定的边界；
//
int main(void) {
    //1、创建套接字socket
    int clientfd = socket(AF_INET, SOCK_STREAM, 0);
    ERROR_CHECK(clientfd, -1, "clientfd");

    struct sockaddr_in serveraddr; //存储空间申请在栈上
    memset(&serveraddr, 0, sizeof(serveraddr));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(8888);//TCP端口号16bit
    serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    //
    //2、向服务器server发起建立连接的请求，connect
    int ret = connect(clientfd, (struct sockaddr* )&serveraddr, sizeof(serveraddr));
    ERROR_CHECK(ret, -1, "connect");
    //printf("sizeof(serveraddr) = %u\n", sizeof(serveraddr));
    printf("connect has complete.\n");

    //3、通信，使用while(1),事件的循环
    char buf[BUFFERSIZE] = {0}; //用户态栈上
    //设置邮箱
    fd_set readfds;
    while (1) {
        //发送，写,写到内核协议栈，并不是由send发送，
        //send写到内核协议栈，数据的发送操作由内核协议栈完成
        //read默认是一个阻塞式函数
        FD_ZERO(&readfds);
        FD_SET(clientfd, &readfds);
        FD_SET(STDIN_FILENO, &readfds);
        select(clientfd + 1, &readfds, NULL, NULL, NULL);

        memset(buf, 0,  sizeof(buf));

        if (FD_ISSET(STDIN_FILENO, &readfds)) {
            int len = read(STDIN_FILENO, buf, sizeof(buf));
            ERROR_CHECK(len, -1, "read");

          //  ret = send(clientfd, buf, len, 0);
            //应该是先发命令，再执行上传的逻辑
            //判断是不是将本地文件上传到服务器的命令，
            //是就需要在本地执行上传
            //1、对命令做一个解析，是上传，并且文件名正确     
            
            do_command(buf, clientfd);

            ////2、若本地不存在这样一个文件，就报一个错误，不执行发送服务器指令
            //若本地存在文件名，发送命令给服务器，执行上传
    }

        //接收，读, 模拟下载文件-----这里还未更改为小火车接收数据！
        memset(buf, 0,  sizeof(buf));
        if (FD_ISSET(clientfd, &readfds)) {
            printf("clientfd is ready.\n");
            ret = recv(clientfd, buf, sizeof(buf), 0);
            printf("ret = %d\n", ret);
            ERROR_CHECK(ret, -1, "recv in client");
            printf("recv from server:\n%s\n", buf);
            if (0 == ret) {
                break;
            }
        }
    }

    //1、关闭打开的文件描述符
    close(clientfd);

    return 0;
}
